#!/usr/bin/env python2.7

# layer_tracker.py

import os, sys
#import re
#from datetime import datetime, timedelta
#from dateutil.parser import parse
import numpy as np
import matplotlib
#matplotlib.use('Agg')
import matplotlib.pyplot as plt
#from mpl_toolkits.basemap import Basemap
#from matplotlib import mlab
from scipy.ndimage import gaussian_filter1d
from netCDF4 import Dataset
from metlib import *
from metlib.lidar import *
from lidarmess.lidar_extra import *

class LidarViewerBase(object):
    def __init__(self, filenames=[], max_height=5000.0, figsize=(12,9)):
        self.fig = plt.figure(figsize=figsize)
        self.tb = plt.get_current_fig_manager().toolbar
        
        self.keyd = dict()

        self.fig.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.fig.canvas.mpl_connect('button_press_event', self.on_button_press)

        self.filenames = filenames
        self.file_i = limited_int(0, 0, len(self.filenames)-1)
        self.max_height = max_height

        self.globald = sys.modules['__main__'].__dict__

    def load_file_i(self, i, force=False):
        old_i = int(self.file_i)
        if i == 'next':
            self.file_i += 1
        elif i == 'prev':
            self.file_i -= 1
        elif isinstance(i, (int, long, np.integer)):
            self.file_i.set_value(i)
        print self.file_i
        if force or int(self.file_i) != old_i:
            self.load_data(self.filenames[int(self.file_i)])

    def load_data(self, fname):
        self.lidard = LidarDataset(fname)
        self.extra = lidar_extra(self.lidard)
        self.lidard.resize_bin(0, height_to_index(self.max_height, self.lidard, self.extra['elev_angle']))
        self.dts = self.lidard['datetime']
        self.dtsnum = matplotlib.dates.date2num(self.dts)
        self.hournum = np.mod(self.dtsnum, 1) * 24.0
        self.height = self.lidard['distance'] * np.sin(np.deg2rad(self.extra['elev_angle']))
        self.binsize = self.lidard['bin_size']

    def update_ax(self, axname):
        if axname == 'norm':
            del self.img_norm
            self.img_norm = self.axnorm.pcolormesh(self.dtsnum, self.height, self.norm, vmin=self.norm_vmin, vmax=self.norm_vmax, cmap=self.cmap)
        elif axname == 'grad':
            del self.img_grad
            self.img_grad = self.axgrad.pcolormesh(self.dtsnum, self.height, self.grad, vmin=self.grad_vmin, vmax=self.grad_vmax, cmap=self.norm_cmap)
        plt.draw()

    def on_key_press(self, event):
        if event.key in ['shift', 'control', 'alt', None]:
            return
        print event.key
        funcname, args, kwargs = self.keyd.get(event.key, ['', (None,), {}]) 
        if funcname.startswith('self.'):
            print funcname[5:]
            try:
                func = getattr(self, funcname[5:])
            except Exception as e:
                print e
                func = self._do_nothing
        else:
            func = self.globald.get(funcname, self._do_nothing)
        print funcname, args
        func(*args, **kwargs)

    def on_button_press(self, event):
        if event.button != 1:
            return
        if event.inaxes not in (self.axnorm, self.axgrad):
            return
        if self.tb.mode != '':
            return
        i, j = self.xy2ij(event.xdata, event.ydata)
        self.current_i = i

    def xy2ij(self, x, y):
        ix = np.argmin(np.abs(x - self.dtsnum))
        jy = np.argmin(np.abs(y - self.height))
        return ix, jy

    def _do_nothing(self, *args, **kwargs):
        print " #### Do_Nothing is called #### "


if __name__ == '__main__':
    lidard = LidarDataset('../data/lidar/stk-20071227.nc')
    tracker = LayerTracker()
#    tracker.load_lidardata(lidard)
#    tracker.calc_lidargrad()
#    print tracker.norm
#    tracker.plot_lidar()
    plt.show()
